package org.web.accesscontrollist.sdk.dto;

import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.web.accesscontrollist.sdk.dto.constant.AclResourceConstant;
import org.web.base.domain.exception.ResultMessageEnum;
import org.web.base.domain.helper.ServiceExceptionHelper;
import org.web.base.domain.helper.ValidationHelper;

import java.util.*;

public class AclResourceHelper implements AclResourceConstant {

    public static void checkSaveAclDetailBatchDTO(SaveAclResourceDetailBatchDTO saveAclResourceDetailBatchDTO) {

        ValidationHelper.validateAndThrow(SaveAclResourceDetailBatchDTO.class, saveAclResourceDetailBatchDTO);
        ValidationHelper.validateAndThrow(DefaultAclResourceDefinition.class, saveAclResourceDetailBatchDTO.getDefaultAclResourceDefinitionDTO());
        ValidationHelper.validateAndThrow(OperatorDTO.class, saveAclResourceDetailBatchDTO.getDefaultAclResourceDefinitionDTO().getOperatorDTO());
        List<String> errorList = new ArrayList<>();
        Map<String, Integer> map = new HashMap<>();
        int i = 0;
        DefaultAclResourceDefinition defaultAclResourceDefinitionDTO = saveAclResourceDetailBatchDTO.getDefaultAclResourceDefinitionDTO();
        for (AclResourceDetailDTO aclResourceDetailDTO : saveAclResourceDetailBatchDTO.getAclResourceDetailDTOList()) {
            aclResourceDetailDTO.setExecuteSuccess(false);
            if (StringUtils.isBlank(aclResourceDetailDTO.getDetailName()) && (ObjectUtils.isNotEmpty(aclResourceDetailDTO.getResourceLevel()) && aclResourceDetailDTO.getResourceLevel() > 0)) {
                // 一定要早于map的构建。不要随意调整该操作的执行顺序.
                aclResourceDetailDTO.setDetailName(buildDetailNameByLevels(aclResourceDetailDTO));
            }
            aclResourceDetailDTO.setDefaultAclResourceDefinitionDTO(defaultAclResourceDefinitionDTO);
            if (map.get(aclResourceDetailDTO.getUniqueKey()) == null) {
                map.put(aclResourceDetailDTO.getUniqueKey(), 1);
            } else {
                map.put(aclResourceDetailDTO.getUniqueKey(), map.get(aclResourceDetailDTO.getUniqueKey()) + 1);
                errorList.add(aclResourceDetailDTO.getUniqueKey() + "有重复，重复" + map.get(aclResourceDetailDTO.getUniqueKey()) + "次。");
            }
            i++;
            checkLevels(i, errorList, aclResourceDetailDTO);
            errorList.addAll(ValidationHelper.validate(AclResourceDetailDTO.class, aclResourceDetailDTO));

        }

        if (ObjectUtils.isNotEmpty(errorList)) {
            throw ServiceExceptionHelper.buildServiceException(ResultMessageEnum.PARAM_INVALID, errorList);
        }
    }

    private static String buildDetailNameByLevels(AclResourceDetailDTO aclResourceDetailDTO) {
        StringBuilder stringBuilder = new StringBuilder();

        for (int i = 1; i <= aclResourceDetailDTO.getResourceLevel(); i++) {
            if (i > 1) {
                stringBuilder.append("-");
            }
            switch (i) {
                case 1:
                    stringBuilder.append(aclResourceDetailDTO.getFirstLevel());
                    break;
                case 2:
                    stringBuilder.append(aclResourceDetailDTO.getSecondLevel());
                    break;
                case 3:
                    stringBuilder.append(aclResourceDetailDTO.getThirdLevel());
                    break;
                case 4:
                    stringBuilder.append(aclResourceDetailDTO.getFourthLevel());
                    break;
                case 5:
                    stringBuilder.append(aclResourceDetailDTO.getFifthLevel());
                    break;
                default:
                    // 当没有匹配的 case 时执行默认代码块
            }
        }

        return stringBuilder.toString();
    }

    private static void checkLevels(int i, List<String> errorList, AclResourceDetailDTO aclResourceDetailDTO) {
        String[] levels = new String[]{aclResourceDetailDTO.getFirstLevel(), aclResourceDetailDTO.getSecondLevel(), aclResourceDetailDTO.getThirdLevel(), aclResourceDetailDTO.getFourthLevel(), aclResourceDetailDTO.getFifthLevel()};

        int resourceLevel = aclResourceDetailDTO.getResourceLevel();

        if (resourceLevel < 0 || resourceLevel > 5) {
            errorList.add("第 " + i + " 条记录，Level 数据设置不合法.");
            return;
        }

        for (int level = 0; level <= resourceLevel; level++) {
            if (StringUtils.isBlank(levels[level])) {
                errorList.add("第 " + i + " 条记录，Level 为 " + level + " 的场合，数据设置不合法.");
            }
        }
    }


    public static void checkSaveUserResourceBindingBatchDTO(SaveUserResourceBindingBatchDTO saveUserResourceBindingBatchDTO) {
        ValidationHelper.validateAndThrow(SaveUserResourceBindingBatchDTO.class, saveUserResourceBindingBatchDTO);
        ValidationHelper.validateAndThrow(OperatorDTO.class, saveUserResourceBindingBatchDTO.getOperatorDTO());
        List<String> errorList = new ArrayList<>();
        OperatorDTO operatorDTO = saveUserResourceBindingBatchDTO.getOperatorDTO();
        for (AclUserResourceBindingDTO aclUserResourceBindingDTO : saveUserResourceBindingBatchDTO.getAclUserResourceBindingDTOList()) {
            aclUserResourceBindingDTO.setExecuteSuccess(false);
            aclUserResourceBindingDTO.setOperatorDTO(operatorDTO);
            errorList.addAll(ValidationHelper.validate(AclUserResourceBindingDTO.class, aclUserResourceBindingDTO));
        }
        if (ObjectUtils.isNotEmpty(errorList)) {
            throw ServiceExceptionHelper.buildServiceException(ResultMessageEnum.PARAM_INVALID, errorList);
        }
    }

    public static void checkSaveAclResourceDefinitionBatch(SaveAclDefinitionBatchDTO saveAclDefinitionBatchDTO) {
        ValidationHelper.validateAndThrow(SaveAclDefinitionBatchDTO.class, saveAclDefinitionBatchDTO);
        ValidationHelper.validateAndThrow(OperatorDTO.class, saveAclDefinitionBatchDTO.getOperatorDTO());

        List<String> errorList = new ArrayList<>();
        OperatorDTO operatorDTO = saveAclDefinitionBatchDTO.getOperatorDTO();
        int i = 0;
        for (AclResourceDefinitionDTO aclResourceDefinitionDTO : saveAclDefinitionBatchDTO.getAclResourceDefinitionDTOList()) {
            aclResourceDefinitionDTO.setExecuteSuccess(false);
            aclResourceDefinitionDTO.setOperatorDTO(operatorDTO);
            errorList.addAll(ValidationHelper.validate(AclResourceDefinitionDTO.class, aclResourceDefinitionDTO));
            i++;
            checkLevels(i, errorList, buildAclDetailLevelsByDefinitionToCheck(aclResourceDefinitionDTO));
        }
        if (ObjectUtils.isNotEmpty(errorList)) {
            throw ServiceExceptionHelper.buildServiceException(ResultMessageEnum.PARAM_INVALID, errorList);
        }
    }

    private static AclResourceDetailDTO buildAclDetailLevelsByDefinitionToCheck(AclResourceDefinitionDTO aclResourceDefinitionDTO) {
        AclResourceDetailDTO aclResourceDetailDTO = new AclResourceDetailDTO();
        aclResourceDetailDTO.setResourceLevel(aclResourceDefinitionDTO.getMaxLevel());
        aclResourceDetailDTO.setFirstLevel(aclResourceDefinitionDTO.getFirstLevelAlias());
        aclResourceDetailDTO.setSecondLevel(aclResourceDefinitionDTO.getSecondLevelAlias());
        aclResourceDetailDTO.setThirdLevel(aclResourceDefinitionDTO.getThirdLevelAlias());
        aclResourceDetailDTO.setFourthLevel(aclResourceDefinitionDTO.getFourthLevelAlias());
        aclResourceDetailDTO.setFifthLevel(aclResourceDefinitionDTO.getFifthLevelAlias());
        return aclResourceDetailDTO;
    }

}
